package ldh.fx.adminfx.controller;

import eu.hansolo.medusa.Gauge;
import eu.hansolo.medusa.GaugeBuilder;
import eu.hansolo.medusa.tools.GradientLookup;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.chart.*;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.Stop;
import javafx.util.Duration;
import ldh.fx.adminfx.cell.ObjectTableCellFactory;
import ldh.fx.adminfx.constant.MouldStatus;
import ldh.fx.adminfx.pojo.Activity;
import ldh.fx.adminfx.pojo.Mould;
import ldh.fx.adminfx.util.ChartUtil;
import ldh.fx.adminfx.util.TableViewUtil;
import ldh.fx.adminfx.util.ThreadPoolUtil;
import org.kordamp.ikonli.fontawesome.FontAwesome;
import org.kordamp.ikonli.javafx.FontIcon;

import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.ResourceBundle;

public class ChartMonitorController implements Initializable {

    @FXML private PieChart qualityPieChart;
    @FXML private BarChart<Number, String> mouldBarChart;
    @FXML private BarChart<Number, String> partBarChart;
    @FXML private LineChart<String, Number> monthMouldLineChart;
    @FXML private LineChart<String, Number> monthPartLineChart;
    @FXML private TableView<Mould> mouldTableView;
    @FXML private TableColumn<Mould, MouldStatus> mouldStatusTableColumn;
    @FXML private PieChart mouldStatusPieChart;
    @FXML private Pane mouldProcessPane;

    @FXML private Pane chartContentPane;
    @FXML private Pane mouldSuccessPane;
    @FXML private Pane partNumPane;
    @FXML private BarChart<String, Number> partSuccessBarChart;
    @FXML private BarChart<String, Number> dayProcedureBarChart;

    // right
    @FXML private BarChart<String, Number> groupSuccessBarChart;
    @FXML private LineChart<Number, Number> daySuccessLineChart;
    @FXML private AreaChart<Number, Number> steelSuccessAreaChart;
    @FXML private AreaChart<Number, Number> machineSuccessAreaChart;
    @FXML private BarChart<String, Number> mouldPartSuccessBarChart;
    @FXML private Pane successPane;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        mouldStatusTableColumn.setCellFactory(new ObjectTableCellFactory<>(s->{
            return s.getDesc();
        }, Pos.CENTER));
        TableViewUtil.alignment(Pos.CENTER, mouldTableView, mouldStatusTableColumn);
        TableViewUtil.width(mouldTableView);

        loadData();

        startTimer();
    }

    private void startTimer() {
        Timeline timeline = new Timeline();
        KeyFrame keyFrame = new KeyFrame(Duration.seconds(10), e->{
            loadData();
        });
        timeline.getKeyFrames().add(keyFrame);
        timeline.setCycleCount(Integer.MAX_VALUE);
        timeline.playFromStart();
    }

    private void loadData() {
        loadMouldBarChartData();
        loadPartBarChartData();
        loadMonthMouldLineCharData();
        ChartUtil.showPopupInfo(monthMouldLineChart);

        loadMonthPartLineCharData();

        loadMouldTableViewData();
        loadMouldStatusPieChartData();
        ChartUtil.showPopupInfo(mouldStatusPieChart);

        ThreadPoolUtil.submit(()->{
            loadMouldProcessChartData();
        });

        // center

        ThreadPoolUtil.submit(()->{
            loadMouldSuccessData();
        });
        ThreadPoolUtil.submit(()->{
            loadPartNumChartData();
        });
        loadPartSuccessBarChartData();
        loadDayProcedureBarChartData();

        // right
        loadQualityPieChartData();
        ChartUtil.showPopupInfo(qualityPieChart);
        loadGroupSuccessBarChartData();
        loadDaySuccessLineChartData();
        loadSteelSuccessAreaChartData();
        loadMachineSuccessAreaChartData();
        loadMouldPartSuccessBarChartData();

        ThreadPoolUtil.submit(()->{
            loadSuccessData();
        });
    }

    private void loadSuccessData() {
        Gauge gauge = GaugeBuilder.create()
                .skinType(Gauge.SkinType.BAR)
                .prefSize(200, 400)
                .foregroundBaseColor(Color.WHITE)
                .barBackgroundColor(Color.WHITE)
                .tickLabelColor(Color.WHITE)
                .decimals(2)
                .value(ChartUtil.random(10, 100))
                .maxValue(100)
                .title("达成率")
                .titleColor(Color.WHITE)
//                .arcExtend(5)
                .gradientLookup(new GradientLookup(new Stop(0, Color.web("#8f62cb")),
                        new Stop(0.25, Color.web("#7367f0")),
                        new Stop(0.5, Color.web("#ad5ea5")),
                        new Stop(0.75, Color.web("#e85456")),
                        new Stop(1.0, Color.web("#e85456").brighter())))
                .gradientBarEnabled(true)
                .animated(true)
                .build();
//        gauge.setStyle("-fx-padding: 5px");
        Platform.runLater(()->{
            if (successPane.getChildren().size() > 1) {
                successPane.getChildren().remove(1);
            }
            successPane.getChildren().add(gauge);
        });
//        mouldSuccessPane.getChildren().add(gauge);
    }

    private void loadMouldPartSuccessBarChartData() {
        mouldPartSuccessBarChart.getData().clear();
        XYChart.Series<String, Number> series1 = new XYChart.Series();
        series1.setName("2020");


        String[] xls = {"CNC", "EDM", "线割", "磨床", "铣床"};
        for(String s : xls) {
            series1.getData().add(new XYChart.Data(s, ChartUtil.random(80, 100)));
        }
        mouldPartSuccessBarChart.getData().add(series1);
    }

    private void loadMachineSuccessAreaChartData() {
        machineSuccessAreaChart.getData().clear();
        XYChart.Series<Number, Number> series1 = new XYChart.Series();
        series1.setName("2020");
        for(int i=0; i<15; i++) {
            series1.getData().add(new XYChart.Data(i+1, ChartUtil.random(0, 120)));
        }
        machineSuccessAreaChart.getData().add(series1);
    }

    private void loadSteelSuccessAreaChartData() {
        steelSuccessAreaChart.getData().clear();
        XYChart.Series<Number, Number> series1 = new XYChart.Series();
        series1.setName("2020");
        for(int i=0; i<15; i++) {
            series1.getData().add(new XYChart.Data(i+1, ChartUtil.random(0, 120)));
        }
        steelSuccessAreaChart.getData().add(series1);
    }

    private void loadDaySuccessLineChartData() {
        daySuccessLineChart.getData().clear();
        XYChart.Series<Number, Number> series1 = new XYChart.Series();
        series1.setName("2020");
        for(int i=0; i<30; i++) {
            series1.getData().add(new XYChart.Data(i+1, ChartUtil.random(0, 120)));
        }
        daySuccessLineChart.getData().add(series1);
    }

    private void loadGroupSuccessBarChartData() {
        groupSuccessBarChart.getData().clear();
        XYChart.Series<String, Number> series1 = new XYChart.Series();
        series1.setName("2020");


        String[] xls = {"CNC", "EDM", "线割", "磨床", "铣床", "外协", "其它"};
        for(String s : xls) {
            series1.getData().add(new XYChart.Data(s, ChartUtil.random(80, 100)));
        }
        groupSuccessBarChart.getData().add(series1);
    }

    private void loadDayProcedureBarChartData() {
        dayProcedureBarChart.getData().clear();
        Random random = new Random();
        XYChart.Series<String, Number> series1 = new XYChart.Series();
        series1.setName("2020");

        XYChart.Series<String, Number> series2 = new XYChart.Series();
        series2.setName("2019");
        for(int i=0; i<12; i++) {
            series1.getData().add(new XYChart.Data((i+1) + "", random.nextInt(200)));
            series2.getData().add(new XYChart.Data((i+1) + "", random.nextInt(200)));
        }

        dayProcedureBarChart.getData().addAll(series1, series2);
    }

    private void loadPartSuccessBarChartData() {
        partSuccessBarChart.getData().clear();
        XYChart.Series<String, Number> series1 = new XYChart.Series();
        series1.setName("2020");
        series1.getData().add(new XYChart.Data("模仁", 600));
        series1.getData().add(new XYChart.Data("镶件", 122));
        series1.getData().add(new XYChart.Data("辅件", 300));
        series1.getData().add(new XYChart.Data("电极", 155));

        XYChart.Series<String, Number> series2 = new XYChart.Series();
        series2.setName("2019");
        series2.getData().add(new XYChart.Data("模仁", 200));
        series2.getData().add(new XYChart.Data("镶件", 100));
        series2.getData().add(new XYChart.Data("辅件", 500));
        series2.getData().add(new XYChart.Data("电极", 200));

        partSuccessBarChart.getData().addAll(series1, series2);
    }

    private void loadPartNumChartData() {
        int value = ChartUtil.random(1000, 5000);
        Gauge gauge = GaugeBuilder.create()
                .skinType(Gauge.SkinType.SLIM)
                .prefSize(200, 400)
                .foregroundBaseColor(Color.WHITE)
                .barBackgroundColor(Color.WHITE)
                .tickLabelColor(Color.WHITE)
                .decimals(2)
                .value(value)
                .maxValue(5000)
                .title(value + "")
                .titleColor(Color.WHITE)
//                .arcExtend(5)
                .gradientLookup(new GradientLookup(new Stop(0, Color.web("#8f62cb")),
                        new Stop(0.25, Color.web("#7367f0")),
                        new Stop(0.5, Color.web("#ad5ea5")),
                        new Stop(0.75, Color.web("#e85456")),
                        new Stop(1.0, Color.web("#e85456").brighter())))
                .gradientBarEnabled(true)
                .animated(true)
                .build();
//        gauge.setStyle("-fx-padding: 5px");
//        Platform.runLater(()->partNumPane.getChildren().add(gauge));
        Platform.runLater(()->{
            if (partNumPane.getChildren().size() > 1) {
                partNumPane.getChildren().remove(1);
            }
            partNumPane.getChildren().add(gauge);
        });
//        partNumPane.getChildren().add(gauge);
    }

    private void loadMouldSuccessData() {
        int value = ChartUtil.random(10, 100);
        Gauge gauge = GaugeBuilder.create()
                .skinType(Gauge.SkinType.BAR)
                .prefSize(200, 200)
                .foregroundBaseColor(Color.WHITE)
                .barBackgroundColor(Color.WHITE)
                .tickLabelColor(Color.WHITE)
                .decimals(2)
                .value(value)
                .maxValue(100)
                .title("达成率")
                .titleColor(Color.WHITE)
//                .arcExtend(5)
                .gradientLookup(new GradientLookup(new Stop(0, Color.web("#8f62cb")),
                        new Stop(0.25, Color.web("#7367f0")),
                        new Stop(0.5, Color.web("#ad5ea5")),
                        new Stop(0.75, Color.web("#e85456")),
                        new Stop(1.0, Color.web("#e85456").brighter())))
                .gradientBarEnabled(true)
                .animated(true)
                .build();
//        gauge.setStyle("-fx-padding: 5px");
//        Platform.runLater(()->mouldSuccessPane.getChildren().add(gauge));
        Platform.runLater(()->{
            if (mouldSuccessPane.getChildren().size() > 1) {
                mouldSuccessPane.getChildren().remove(1);
            }
            mouldSuccessPane.getChildren().add(gauge);
        });
//        mouldSuccessPane.getChildren().add(gauge);
    }

    private void loadMouldProcessChartData() {
        int value = ChartUtil.random(10, 100);
        Gauge gauge = GaugeBuilder.create()
                .skinType(Gauge.SkinType.GAUGE)
//                .prefSize(400, 400)
                .foregroundBaseColor(Color.web("#88ada6"))
                .barBackgroundColor(Color.web("#6b98b4"))
                .tickLabelColor(Color.WHITE)
                .decimals(10)
                .value(value)
                .maxValue(100)
                .subTitle(value + "")
                .subTitleColor(Color.WHITE)
//                .arcExtend(5)
                .gradientLookup(new GradientLookup(new Stop(0, Color.web("#8f62cb")),
                        new Stop(0.25, Color.web("#7367f0")),
                        new Stop(0.5, Color.web("#ad5ea5")),
                        new Stop(0.75, Color.web("#e85456")),
                        new Stop(1.0, Color.web("#e85456").brighter())))
                .gradientBarEnabled(true)
//                .animated(true)
                .build();
//        gauge.setStyle("-fx-padding: 5px");
        Platform.runLater(()->{
            if (mouldProcessPane.getChildren().size() > 1) {
                mouldProcessPane.getChildren().remove(1);
            }
            mouldProcessPane.getChildren().add(gauge);
        });
    }

    private void loadMouldStatusPieChartData() {
        mouldStatusPieChart.getData().clear();
        String[] xls = {"正常交付", "加工中", "延期"};
        for(String s : xls) {
            mouldStatusPieChart.getData().add(new PieChart.Data(s, ChartUtil.random(30, 60)));
        }
    }

    private BarChart<Number, String> loadMouldBarChartData() {
        mouldBarChart.getData().clear();
        XYChart.Series<Number, String> series1 = new XYChart.Series();
        series1.setName("2003");

        XYChart.Series<Number, String> series2 = new XYChart.Series();
        series2.setName("2004");

        String[] xls = {"设变", "修模", "新模"};
        for(String s : xls) {
            series1.getData().add(new XYChart.Data(ChartUtil.randomDouble(10.0, 50.0), s));
            series2.getData().add(new XYChart.Data(10.0, s));
        }

        mouldBarChart.getData().addAll(series1, series2);
        return mouldBarChart;
    }

    private void loadPartBarChartData() {
        partBarChart.getData().clear();
        XYChart.Series<Number, String> series1 = new XYChart.Series();
        series1.setName("2003");

        XYChart.Series<Number, String> series2 = new XYChart.Series();
        series2.setName("2004");

        String[] xls = {"设变", "修模", "新模"};
        for(String s : xls) {
            series1.getData().add(new XYChart.Data(ChartUtil.randomDouble(1.0, 10.0), s));
            series2.getData().add(new XYChart.Data(ChartUtil.randomDouble(1.0, 10.0), s));
        }

        partBarChart.getData().addAll(series1, series2);
    }

    private void loadMonthMouldLineCharData() {
        monthMouldLineChart.getData().clear();
        XYChart.Series series = new XYChart.Series();
        series.setName("data1");

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("2");

        String[] xls = {"一月份", "二月份", "三月份", "四月份", "五月份", "六月份", "七月份", "八月份", "九月份", "十月份", "十一月份", "十二月份"};
        for(String s : xls) {
            series.getData().add(new XYChart.Data(s, ChartUtil.random(10, 50)));
            series2.getData().add(new XYChart.Data(s, ChartUtil.random(10, 50)));
        }

        monthMouldLineChart.getData().addAll(series, series2);
    }

    private void loadMonthPartLineCharData() {
        monthPartLineChart.getData().clear();
        XYChart.Series series = new XYChart.Series();
        series.setName("data-1");

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("data-2");

        String[] xls = {"一月份", "二月份", "三月份", "四月份", "五月份", "六月份", "七月份", "八月份", "九月份", "十月份", "十一月份", "十二月份"};
        for(String s : xls) {
            series.getData().add(new XYChart.Data(s, ChartUtil.random(10, 50)));
            series2.getData().add(new XYChart.Data(s, ChartUtil.random(10, 50)));
        }

        monthPartLineChart.getData().addAll(series, series2);
    }

    private void loadMouldTableViewData() {
        List<Mould> moulds = new ArrayList<>();
        Random random = new Random();
        for(int i=0; i<10; i++) {
            Mould mould = new Mould(i, "no" + random.nextInt(100), "1.0.4", "修模", MouldStatus.getByValue(random.nextInt(10)/3));loadMonthMouldLineCharData();
            moulds.add(mould);
        }
        mouldTableView.getItems().addAll(moulds);
    }

    private void loadQualityPieChartData() {
        qualityPieChart.getData().clear();
        ObservableList<PieChart.Data> pieChartData =
                FXCollections.observableArrayList(
                        new PieChart.Data("Grapefruit", ChartUtil.random(10, 50)),
                        new PieChart.Data("Oranges", ChartUtil.random(10, 50)),
                        new PieChart.Data("Apples", ChartUtil.random(10, 50)));
        qualityPieChart.setData(pieChartData);

        qualityPieChart.setLabelsVisible(false);
        qualityPieChart.setLegendSide(Side.BOTTOM);

    }

}
